package org.eclipse.rally.plugin.utils;

import java.io.File;

import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.internal.win32.OS;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.ole.win32.OLE;
import org.eclipse.swt.ole.win32.OleAutomation;
import org.eclipse.swt.ole.win32.OleControlSite;
import org.eclipse.swt.ole.win32.OleFrame;
import org.eclipse.swt.ole.win32.Variant;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class FileViewer {

	static int CodePage = OS.GetACP();

	public static void viewFile(File file) {
		Shell shell = new Shell();
		shell.setLayout(new GridLayout(2, false));

		final Text text = new Text(shell, SWT.BORDER);
		text
				.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false,
						1, 1));
		text.setVisible(false);
		OleFrame oleFrame = new OleFrame(shell, SWT.NONE);
		oleFrame.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2,
				1));
		OleControlSite controlSite;
		OleAutomation automation;
		try {
			controlSite = new OleControlSite(oleFrame, SWT.NONE,
					"Shell.Explorer");
			automation = new OleAutomation(controlSite);
			controlSite.doVerb(OLE.OLEIVERB_INPLACEACTIVATE);
		} catch (SWTException ex) {
			return;
		}

		final OleAutomation auto = automation;

		// Read PostData whenever we navigate to a site that uses it
		int BeforeNavigate2 = 0xfa;

		try {
			System.out.println("pATH ==" + file.getAbsolutePath());
			text.setText("file://" + file.getAbsolutePath());
		} catch (Exception e) {
			e.printStackTrace();
		}
		int[] rgdispid = automation.getIDsOfNames(new String[] { "Navigate",
				"URL", "PostData" });
		int dispIdMember = rgdispid[0];
		Variant[] rgvarg = new Variant[2];
		rgvarg[0] = new Variant(text.getText());
		rgvarg[1] = writeSafeArray("hello world");
		int[] rgdispidNamedArgs = new int[2];
		rgdispidNamedArgs[0] = rgdispid[1];
		rgdispidNamedArgs[1] = rgdispid[2];
		automation.invoke(dispIdMember, rgvarg, rgdispidNamedArgs);

		shell.open();
	}

	static Variant writeSafeArray(String string) {
		short cDims = 1;
		short FADF_FIXEDSIZE = 0x10;
		short FADF_HAVEVARTYPE = 0x80;
		short fFeatures = (short) (FADF_FIXEDSIZE | FADF_HAVEVARTYPE);
		int cbElements = 1;
		int count = string.length();
		char[] chars = new char[count + 1];
		string.getChars(0, count, chars, 0);
		int cchMultiByte = OS.WideCharToMultiByte(CodePage, 0, chars, -1, null,
				0, null, null);
		if (cchMultiByte == 0)
			return null;
		int pvData = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT,
				cchMultiByte);
		OS.WideCharToMultiByte(CodePage, 0, chars, -1, pvData, cchMultiByte,
				null, null);
		int cElements1 = cchMultiByte;
		int lLbound1 = 0;
		int sizeofSafeArray = 12 + 4 + 1 * 8;
		int pSafeArray = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT,
				sizeofSafeArray);
		int offset = 0;
		OS.MoveMemory(pSafeArray + offset, new short[] { cDims }, 2);
		offset += 2;
		OS.MoveMemory(pSafeArray + offset, new short[] { fFeatures }, 2);
		offset += 2;
		OS.MoveMemory(pSafeArray + offset, new int[] { cbElements }, 4);
		offset += 4;
		OS.MoveMemory(pSafeArray + offset, new int[] { 0 }, 4);
		offset += 4;
		OS.MoveMemory(pSafeArray + offset, new int[] { pvData }, 4);
		offset += 4;
		OS.MoveMemory(pSafeArray + offset, new int[] { cElements1 }, 4);
		offset += 4;
		OS.MoveMemory(pSafeArray + offset, new int[] { lLbound1 }, 4);
		offset += 4;
		int pVariant = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT,
				Variant.sizeof);
		short vt = (short) (OLE.VT_ARRAY | OLE.VT_UI1);
		OS.MoveMemory(pVariant, new short[] { vt }, 2);
		OS.MoveMemory(pVariant + 8, new int[] { pSafeArray }, 4);
		Variant variantByRef = new Variant(pVariant,
				(short) (OLE.VT_BYREF | OLE.VT_VARIANT));
		return variantByRef;
	}
}
